﻿using Abp.Auditing;
using Abp.Domain.Repositories;
using Abp.Extensions;
using System.Threading.Tasks;

namespace AbpProjectTemplate.Components.Auditing
{
    public class AppAuditingStore : IAuditingStore
    {
        public static int MaxParametersLength = 50000;

        private readonly IRepository<AuditLog, long> _auditLogRepository;

        public AppAuditingStore(IRepository<AuditLog, long> auditLogRepository)
        { this._auditLogRepository = auditLogRepository; }

        public AuditLog CreateFromAuditInfo(AuditInfo auditInfo)
        {
            var exceptionMessage = AuditLog.GetAbpClearException(auditInfo.Exception);
            return new AuditLog
            {
                TenantId = auditInfo.TenantId,
                UserId = auditInfo.UserId,
                ServiceName = auditInfo.ServiceName.TruncateWithPostfix(AuditLog.MaxServiceNameLength),
                MethodName = auditInfo.MethodName.TruncateWithPostfix(AuditLog.MaxMethodNameLength),
                Parameters = auditInfo.Parameters.TruncateWithPostfix(AuditLog.MaxParametersLength),
                ReturnValue = auditInfo.ReturnValue.TruncateWithPostfix(AuditLog.MaxReturnValueLength),
                ExecutionTime = auditInfo.ExecutionTime,
                ExecutionDuration = auditInfo.ExecutionDuration,
                ClientIpAddress = auditInfo.ClientIpAddress.TruncateWithPostfix(AuditLog.MaxClientIpAddressLength),
                ClientName = auditInfo.ClientName.TruncateWithPostfix(AuditLog.MaxClientNameLength),
                BrowserInfo = auditInfo.BrowserInfo.TruncateWithPostfix(AuditLog.MaxBrowserInfoLength),
                Exception = exceptionMessage.TruncateWithPostfix(AuditLog.MaxExceptionLength),
                ImpersonatorUserId = auditInfo.ImpersonatorUserId,
                ImpersonatorTenantId = auditInfo.ImpersonatorTenantId,
                CustomData = auditInfo.CustomData.TruncateWithPostfix(AuditLog.MaxCustomDataLength)
            };
        }

        public virtual Task SaveAsync(AuditInfo auditInfo)
        { return this._auditLogRepository.InsertAsync(this.CreateFromAuditInfo(auditInfo)); }

        public virtual void Save(AuditInfo auditInfo)
        { this._auditLogRepository.Insert(this.CreateFromAuditInfo(auditInfo)); }
    }
}
